﻿namespace ScrumLite.WebUx.JsonProxy
{
    using System;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Net;
    using System.ServiceModel;
    using System.ServiceModel.Web;
    using ScrumLite.Services;
    using ScrumLite.Services.Contracts;
    using System.Globalization;

    [ServiceContract(Namespace = "")]
    public class Defects
    {
        IDefectsService defects;

        const int defectsperpage = 20;

        public Defects()
            : this(new LinqDefectsService())
        {
        }

        public Defects(IDefectsService defects)
        {
            this.defects = defects;
        }

        [OperationContract]
        [WebGet(UriTemplate = "ReadByDeliverable?project={projectId}&deliverable={deliverableId}", ResponseFormat = WebMessageFormat.Json)]
        public Defect[] GetByDeliverable(string projectId, string deliverableId)
        {
            Defect[] data = this.defects.GetDefectsByDeliverable(projectId, deliverableId);
            Defects.SetCaching(WebOperationContext.Current, DateTime.Now, 10); // 10 seconds
            return data;
        }

        [OperationContract]
        [WebGet(UriTemplate = "ReadAll?project={projectId}&nTriaged={notTriaged}", ResponseFormat = WebMessageFormat.Json)]
        public Defect[] GetAll(string projectId, byte notTriaged)
        {
            Collection<Defect> data = this.defects.GetDefects(projectId, notTriaged);
            Defects.SetCaching(WebOperationContext.Current, DateTime.Now, 10); // 10 seconds
            return data.ToArray();
        }

        [OperationContract]
        [WebGet(UriTemplate = "ReadPage?project={projectId}&nPage={pageNumber}&nTriaged={notTriaged}&deliverable={deliverableId}", ResponseFormat = WebMessageFormat.Json)]
        public DefectPage GetPage(string projectId, int pageNumber, byte notTriaged, string deliverableId)
        {
            Collection<Defect> data;

            if (String.IsNullOrEmpty(deliverableId))
            {
                data = this.defects.GetDefects(projectId, notTriaged);
            }
            else
            {
                data = new Collection<Defect>(this.defects.GetDefectsByDeliverable(projectId, deliverableId).ToArray());
            }
            

            int npages = data.Count / defectsperpage;

            if (data.Count % defectsperpage != 0)
                npages++;

            if (pageNumber < 0)
                pageNumber = npages - 1;

            Defects.SetCaching(WebOperationContext.Current, DateTime.Now, 10); // 10 seconds

            Collection<Defect> result = new Collection<Defect>();

            for (int k = pageNumber * defectsperpage; k < data.Count && k < (pageNumber + 1) * defectsperpage; k++)
                result.Add(data[k]);

            DefectPage page = new DefectPage();
            page.NoPage = pageNumber;
            page.NoPages = npages;
            page.Defects = result.ToArray();
            return page;
        }

        [OperationContract]
        [WebInvoke(UriTemplate = "Delete?id={id}", RequestFormat = WebMessageFormat.Json)]
        public void DeleteDefect(Guid id)
        {
            this.defects.DeleteDefect(id);
        }

        [OperationContract]
        [WebInvoke(UriTemplate = "Write", RequestFormat = WebMessageFormat.Json)]
        public void Write(Defect[] data)
        {
            this.defects.SaveDefects(data);
        }

        private static void SetCaching(WebOperationContext context, DateTime lastModifiedDate, Int32 maxCacheAge)
        {
            // set CacheControl header
            HttpResponseHeader cacheHeader = HttpResponseHeader.CacheControl;
            String cacheControlValue = String.Format(CultureInfo.InvariantCulture, "max-age={0}, must-revalidate", maxCacheAge);
            context.OutgoingResponse.Headers.Add(cacheHeader, cacheControlValue);

            // set cache validation 
            context.OutgoingResponse.LastModified = lastModifiedDate;
            String tag = context.IncomingRequest.UriTemplateMatch.RequestUri.ToString() + lastModifiedDate.ToString();
            context.OutgoingResponse.ETag = tag;
        }
    }
}
